{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "All work completed\n",
      "Working on 0\n",
      "Finished 0\n",
      "Working on 1\n",
      "Finished 1\n",
      "Working on 2\n",
      "Finished 2\n",
      "Working on 3\n",
      "Finished 3\n",
      "Working on 4\n",
      "Finished 4\n"
     ]
    }
   ],
   "source": [
    "import threading, queue\n",
    "import time\n",
    "q = queue.Queue()\n",
    "# send thirty task requests to the worker\n",
    "def send():\n",
    "    time.sleep(1)\n",
    "    for item in range(5):\n",
    "        q.put(item)\n",
    "    # print('All task requests sent\\n', end='')\n",
    "\n",
    "def worker():\n",
    "    # time.sleep(1)\n",
    "    while True:\n",
    "        item = q.get()\n",
    "        print(f'Working on {item}')\n",
    "        print(f'Finished {item}')\n",
    "        q.task_done()\n",
    "\n",
    "threading.Thread(target=worker).start()\n",
    "threading.Thread(target=send).start()\n",
    "# turn-on the worker thread\n",
    "# block until all tasks are done\n",
    "q.join()\n",
    "print('All work completed')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import threading, queue\n",
    "\n",
    "q = queue.Queue()\n",
    "\n",
    "def worker():\n",
    "    while True:\n",
    "        item = q.get()\n",
    "        print(f'Working on {item}')\n",
    "        print(f'Finished {item}')\n",
    "        q.task_done()\n",
    "\n",
    "# turn-on the worker thread\n",
    "threading.Thread(target=worker, daemon=True).start()\n",
    "\n",
    "# send thirty task requests to the worker\n",
    "for item in range(30):\n",
    "    q.put(item)\n",
    "print('All task requests sent\\n', end='')\n",
    "\n",
    "# block until all tasks are done\n",
    "q.join()\n",
    "print('All work completed')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello\n"
     ]
    }
   ],
   "source": [
    "print('hello')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "from queue import Queue\n",
    "a = Queue(1)\n",
    "a.put(1)\n",
    "a.put(1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "f 9\n",
      "t 12\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "(None, None)"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def gen():\n",
    "    while True:\n",
    "        t = yield from it()\n",
    "        print('t',t)\n",
    "\n",
    "def it():\n",
    "    f = yield\n",
    "    print('f',f)\n",
    "    return f + 3\n",
    "\n",
    "coro = gen()\n",
    "a = next(coro)\n",
    "b = coro.send(9)\n",
    "\n",
    "a, b\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " 9 boys  averaging 40.42kg\n",
      " 9 boys  averaging 1.39m\n",
      "10 girls averaging 42.04kg\n",
      "10 girls averaging 1.43m\n"
     ]
    }
   ],
   "source": [
    "from collections import namedtuple\n",
    "Result = namedtuple('Result', 'count average')\n",
    "# 子生成器\n",
    "def averager():\n",
    "    total = 0.0\n",
    "    count = 0\n",
    "    average = None\n",
    "    while True:\n",
    "        term = yield\n",
    "        if term is None: \n",
    "            break\n",
    "        total += term\n",
    "        count += 1\n",
    "        average = total/count\n",
    "    return Result(count, average)\n",
    "\n",
    "# 委派生成器\n",
    "def grouper(results, key):\n",
    "    while True:\n",
    "        results[key] = yield from averager()\n",
    "# 客户端代码，即调用方\n",
    "def main(data): \n",
    "    results = {}\n",
    "    for key, values in data.items():\n",
    "        group = grouper(results, key) \n",
    "        next(group) \n",
    "        for value in values:\n",
    "            group.send(value)\n",
    "        group.send(None) # 重要！\n",
    "    # print(results) # 如果要调试，去掉注释\n",
    "    report(results)\n",
    "# 输出报告\n",
    "def report(results):\n",
    "    for key, result in sorted(results.items()):\n",
    "        group, unit = key.split(';')\n",
    "        print('{:2} {:5} averaging {:.2f}{}'.format(\n",
    "            result.count, group, result.average, unit))\n",
    "\n",
    "data = {\n",
    "'girls;kg':\n",
    "[40.9, 38.5, 44.3, 42.2, 45.2, 41.7, 44.5, 38.0, 40.6, 44.5],\n",
    "'girls;m':\n",
    "[1.6, 1.51, 1.4, 1.3, 1.41, 1.39, 1.33, 1.46, 1.45, 1.43],\n",
    "'boys;kg':\n",
    "[39.0, 40.8, 43.2, 40.8, 43.1, 38.6, 41.4, 40.6, 36.3],\n",
    "'boys;m':\n",
    "[1.38, 1.5, 1.32, 1.25, 1.37, 1.48, 1.25, 1.49, 1.46],\n",
    "}\n",
    "if __name__ == '__main__':\n",
    "    main(data)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "usage: ipykernel_launcher.py [-h] [-e END_TIME] [-t TAXIS] [-s SEED]\n",
      "ipykernel_launcher.py: error: unrecognized arguments: --ip=127.0.0.1 --stdin=9003 --control=9001 --hb=9000 --Session.signature_scheme=\"hmac-sha256\" --Session.key=b\"a67f8daf-d5df-4a99-8899-7bc7bf95e748\" --shell=9002 --transport=\"tcp\" --iopub=9004 --f=C:\\Users\\DELL\\AppData\\Local\\Temp\\tmp-1452g6Y3sK43z4Gz.json\n"
     ]
    },
    {
     "ename": "SystemExit",
     "evalue": "2",
     "output_type": "error",
     "traceback": [
      "An exception has occurred, use %tb to see the full traceback.\n",
      "\u001b[1;31mSystemExit\u001b[0m\u001b[1;31m:\u001b[0m 2\n"
     ]
    }
   ],
   "source": [
    "import random\n",
    "import collections\n",
    "import queue\n",
    "import argparse\n",
    "import time\n",
    "DEFAULT_NUMBER_OF_TAXIS = 3\n",
    "DEFAULT_END_TIME = 180\n",
    "SEARCH_DURATION = 5\n",
    "TRIP_DURATION = 20\n",
    "DEPARTURE_INTERVAL = 5\n",
    "Event = collections.namedtuple('Event', 'time proc action')\n",
    "\n",
    "# BEGIN TAXI_PROCESS\n",
    "def taxi_process(ident, trips, start_time=0):\n",
    "    \"\"\"每次状态变化时向仿真程序产出一个事件\"\"\"\n",
    "    time = yield Event(start_time, ident, 'leave garage')\n",
    "    for i in range(trips):\n",
    "        time = yield Event(time, ident, 'pick up passenger')\n",
    "        time = yield Event(time, ident, 'drop off passenger')\n",
    "    yield Event(time, ident, 'going home')\n",
    "    # 结束出租车进程\n",
    "# END TAXI_PROCESS\n",
    "# BEGIN TAXI_SIMULATOR\n",
    "class Simulator:\n",
    "    def __init__(self, procs_map):\n",
    "        self.events = queue.PriorityQueue()\n",
    "        self.procs = dict(procs_map)\n",
    "    def run(self, end_time):\n",
    "        \"\"\"调度并显示事件，直到时间结束\"\"\"\n",
    "        # 调度各辆出租车的第一个事件\n",
    "        for _, proc in sorted(self.procs.items()):\n",
    "            first_event = next(proc)\n",
    "            self.events.put(first_event)\n",
    "        # 此次仿真的主循环\n",
    "        sim_time = 0\n",
    "        while sim_time < end_time:\n",
    "            if self.events.empty():\n",
    "                print('*** end of events ***')\n",
    "                break\n",
    "            current_event = self.events.get()\n",
    "            sim_time, proc_id, previous_action = current_event\n",
    "            print('taxi:', proc_id, proc_id * ' ', current_event)\n",
    "            active_proc = self.procs[proc_id]\n",
    "            next_time = sim_time + compute_duration(previous_action)\n",
    "            try:\n",
    "                next_event = active_proc.send(next_time)\n",
    "            except StopIteration:\n",
    "                del self.procs[proc_id]\n",
    "            else:\n",
    "                self.events.put(next_event)\n",
    "        else:\n",
    "            msg = '*** end of simulation time: {} events pending ***'\n",
    "            print(msg.format(self.events.qsize()))\n",
    "# END TAXI_SIMULATOR\n",
    "def compute_duration(previous_action):\n",
    "    \"\"\"使用指数分布计算操作的耗时\"\"\"\n",
    "    if previous_action in ['leave garage', 'drop off passenger']:\n",
    "\n",
    "        # 新状态是四处徘徊\n",
    "        interval = SEARCH_DURATION\n",
    "    elif previous_action == 'pick up passenger':\n",
    "        # 新状态是行程开始\n",
    "        interval = TRIP_DURATION\n",
    "    elif previous_action == 'going home':\n",
    "        interval = 1\n",
    "    else:\n",
    "        raise ValueError('Unknown previous_action: %s' % previous_action)\n",
    "    return int(random.expovariate(1/interval)) + 1\n",
    "def main(end_time=DEFAULT_END_TIME, num_taxis=DEFAULT_NUMBER_OF_TAXIS,\n",
    "    seed=None):\n",
    "    \"\"\"初始化随机生成器，构建过程，运行仿真程序\"\"\"\n",
    "    if seed is not None:\n",
    "        random.seed(seed) # 获得可复现的结果\n",
    "    taxis = {i: taxi_process(i, (i+1)*2, i*DEPARTURE_INTERVAL)\n",
    "        for i in range(num_taxis)}\n",
    "    sim = Simulator(taxis)\n",
    "    sim.run(end_time)\n",
    "if __name__ == '__main__':\n",
    "    parser = argparse.ArgumentParser(\n",
    "        description='Taxi fleet simulator.')\n",
    "    parser.add_argument('-e', '--end-time', type=int,\n",
    "        default=DEFAULT_END_TIME,\n",
    "        help='simulation end time; default = %s'\n",
    "        % DEFAULT_END_TIME)\n",
    "    parser.add_argument('-t', '--taxis', type=int,\n",
    "        default=DEFAULT_NUMBER_OF_TAXIS,\n",
    "        help='number of taxis running; default = %s'\n",
    "        % DEFAULT_NUMBER_OF_TAXIS)\n",
    "    parser.add_argument('-s', '--seed', type=int, default=None,\n",
    "        help='random generator seed (for testing)')\n",
    "    args = parser.parse_args()\n",
    "    main(args.end_time, args.taxis, args.seed)\n"
   ]
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "304fe461dc7a51a7d37635154b9407ecc2c880777499052fc195a7e0f9e1dfee"
  },
  "kernelspec": {
   "display_name": "Python 3.9.7 ('SciencePY')",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
